#include <rtthread.h>
#include <webclient.h>
#include <rtdebug.h>

#include <rtdbg.h>
//#include "main.h"
#include <stdbool.h>

#include <stdbool.h>
#include <string.h>
#include <stdio.h>
//personal
//#include "util.h"
//os & hal & bsp
#include <rtthread.h>
#include <rtdevice.h>
#include <webclient.h>
#include <GET_TEST_main.h>
#define TARGET_URL    "http://101.37.75.201:8000/api/post"
#define HTTP_BUF_SIZE      (1024) // 64KB buffer

// 增加主线程栈大小
#define MAIN_THREAD_STACK_SIZE (8192) // 8KB栈
#define MAIN_THREAD_PRIO       25

void cache(uint8_t content)
{
    if (photo_buf.cached_len >= PHOTO_BUF_SIZE)
    {
        LOG_E("overflow");
        return;
    }
    photo_buf.CONTENT[photo_buf.cached_len] = content;
    photo_buf.cached_len++;
}

photo_buf_struct photo_buf;

int http_test(void* content, size_t len, bool end)
{
    char final_url[0x100];
    memset(final_url, 0, sizeof(final_url));
    rt_snprintf(final_url, sizeof(final_url), "%s?end=%d",
    TARGET_URL, end); // 使用rt_snprintf避免溢出
    LOG_W("Send POST request to %s", final_url);

    struct webclient_session* session = RT_NULL;
    char* buffer = RT_NULL; // 使用堆分配

    buffer = (char*) rt_malloc(HTTP_BUF_SIZE);
    if (buffer == RT_NULL)
    {
        LOG_E("Memory allocation failed");
        return -1;
    }

    session = webclient_session_create(HTTP_BUF_SIZE);
    if (session == RT_NULL)
    {
        LOG_E("Session create failed");
        rt_free(buffer);
        return -1;
    }

    // 设置请求头
    char content_type[] =
            "Content-Type: application/x-www-form-urlencoded\r\n";
    int content_type_result = webclient_header_fields_add(
            session, content_type);
    if (content_type_result < 0)
    {
        LOG_E(
                "Add Content-Type header failed, error code: %d",
                content_type_result);
        goto _exit;
    }

    char content_length[64];
    rt_snprintf(content_length, sizeof(content_length),
            "Content-Length: %ld\r\n", len);
    int content_length_result = webclient_header_fields_add(
            session, content_length);
    if (content_length_result < 0)
    {
        LOG_E(
                "Add Content-Length header failed, error code: %d",
                content_length_result);
        goto _exit;
    }

    // 发送POST请求
    int status = webclient_post(session, final_url, content,
            len);
    if (status != 200)
    {
        LOG_E("HTTP failed with status: %d", status);
        goto _exit;
    }

    LOG_W("POST finished");

    int bytes_read, total_bytes = 0;
//    while ((bytes_read = webclient_read(session, buffer,
//    HTTP_BUF_SIZE - 1)) > 0)
//    {
//        buffer[bytes_read] = '\0';
//        LOG_D("Received %d bytes:\n%s", bytes_read, buffer);
//        total_bytes += bytes_read;
//    }
    for (;;)
    {
        bytes_read = webclient_read(session, buffer,
        HTTP_BUF_SIZE - 1);
        if (bytes_read <= 0) break;
        buffer[bytes_read] = '\0';
        LOG_D("Received %d bytes:\n%s", bytes_read, buffer);
        total_bytes += bytes_read;
    }

    if (bytes_read == 0)
    {
        LOG_I("Server closed the connection");
    }
    else
    {
        LOG_E("Read error: %d", bytes_read);
    }

    LOG_I("Response received successfully. Total: %d bytes",
            total_bytes);

    _exit: if (session)
    {
        webclient_close(session);
    }
    if (buffer)
    {
        rt_free(buffer);
    }
    return 0;
}

// 主线程入口
void my_main_thread_entry(void* parameter)
{
    // 模拟POST数据
    uint8_t* data = RT_NULL;
    size_t data_len = 0;

    // 初始化数据（根据实际情况修改）
    data = (uint8_t*) "Hello, Server!";
    data_len = rt_strlen((char* )data);

    http_test(data, data_len, 1);
    http_test(data, data_len, 1);

    photo_buf.cached_len = 0;

    init();
    rt_kprintf("start ptc-06");
    if (reset(&camera))
    {
        rt_kprintf("reset fail\n");
    }
    rt_kputs("clear cache");
    if (clear_photo_cache(&camera))
    {
        rt_kprintf("clear cache fail\n");
    }
    int count = 0;
    for (;; count++)
    {
        rt_thread_mdelay(500);
        if (take_photo(&camera))
        {
            rt_kprintf("take photo fail\n");
            continue;
        }
        rt_thread_mdelay(100);
        uint16_t photo_size;
        if (get_photo_size(&camera, &photo_size))
        {
            rt_kprintf("get photo size fail\n");
            continue;
        }
        //        rt_thread_mdelay(1000);
        rt_kprintf("photo size: %d\n", photo_size);
        //        uint8_t* photo_data = rt_malloc(photo_size); //图片数据
        //        if (get_photo_data(photo_size, photo_data))
        if (get_photo_binary(&camera, photo_size,
                (RT_SERIAL_RB_BUFSZ - 10) / 8 * 8))
        {
            rt_kprintf("get photo data fail\n");
            continue;
        }

        // buffer received, send
        LOG_I("%s buffer size: %d", __FILE__,
                photo_buf.cached_len);
        if (photo_buf.cached_len % 2 != 0)
        {
            cache((uint8_t) 0);
        }

        http_test(photo_buf.CONTENT,
                (photo_buf.cached_len) * sizeof(uint8_t)
                        / sizeof(uint16_t), 0);

        photo_buf.cached_len = 0;

        //sent, clear buffer
        if (camera.clear_photo_cache(&camera))
        {
            rt_kprintf("clear cache fail\n");
            continue;
        }
    }
}
int wifi();
// 初始化主线程
int main(void)
{
    rt_thread_t main_thread;

    wifi();
//    main_thread = rt_thread_create("main",
//            my_main_thread_entry,
//            RT_NULL,
//            MAIN_THREAD_STACK_SIZE,
//            MAIN_THREAD_PRIO, 10);
//
//    if (main_thread != RT_NULL)
//    {
//        rt_thread_startup(main_thread);
//    }
    my_main_thread_entry(0);

    return 0;
}

#include <rtthread.h>
#include <rthw.h>
#include <wlan_mgnt.h>
#include <wlan_cfg.h>
#include <wlan_prot.h>

//#include <netif/ethernetif.h>
//#include <lwip/netif.h>
//#include <lwip/ip_addr.h>
//
#include <rtdevice.h>
//#include <wlan_dev.h>

#define WIFI_SSID       "NetworkNotFound"
#define WIFI_PASSWORD   "a7btngqx"
int wifi()
{
    rt_err_t result;
    for (;;)
    {
        result = rt_wlan_connect(WIFI_SSID, WIFI_PASSWORD);
        rt_thread_mdelay(500);
        if (result != RT_EOK)
        {
            LOG_E("%s failed with code %d\n", __FILE__,
                    result);
            continue;
        }
        LOG_W("%s:connection success\n", __FILE__);
        break;
    }
    rt_thread_mdelay(2000);
}
